package cn.bdqn.config.shiro;

import cn.bdqn.pojo.Role;
import cn.bdqn.pojo.SysRight;
import cn.bdqn.pojo.User;
import cn.bdqn.service.RoleService;
import cn.bdqn.service.SysRightService;
import cn.bdqn.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class MyRealm extends AuthorizingRealm {
    @Resource
    UserService userService;
    @Resource
    StringRedisTemplate stringRedisTemplate;
    @Resource
    RoleService roleService;

    @Resource
    SysRightService sysRightService;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        User user = (User)principalCollection.getPrimaryPrincipal();
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        //获取权限
        info.addRole(user.getRole().getRoleName());
//        Role role = user.getRole();
        //根据当前用户的id查询出角色信息
        Role role = roleService.selectByUserId(user.getUsrId());
        if (role!=null){
            info.addRole(role.getRoleName());
//            List<SysRight> rights = role.getRights();
            List<SysRight> rights = sysRightService.selectRoleId(role.getRoleId());
            for (SysRight right : rights) {
                info.addStringPermission(right.getRightCode());
            }
        }
        return info;
    }
    //这个认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token= (UsernamePasswordToken)authenticationToken;
        //redis操作类
        ValueOperations<String, String> vo = stringRedisTemplate.opsForValue();
        //登录计数器并自增
        vo.increment("shiro_login_count"+token.getUsername()+token.getUsername(),1);
        //判断计数器次数
        if (Integer.parseInt(vo.get("shiro_login_count"+token.getUsername()+token.getUsername()))>5){
            //存进一个key为锁的值
            vo.set("shiro_is_lock_"+token.getUsername()+token.getUsername(),"lock",1, TimeUnit.HOURS);
            //删除
            stringRedisTemplate.delete("shiro_login_count"+token.getUsername()+token.getUsername());
        }
        //判断账号是否冻结了
        if (("lock").equals(vo.get("shiro_is_lock_"+token.getUsername()+token.getUsername()))){
            throw new DisabledAccountException("账号被冻结");
        }
        User user = userService.getUserByUsrName(token.getUsername());
        if (user==null){
            throw new UnknownAccountException("账号不存在");
        }
        if (user.getUsrFlag()==0){
            throw  new LockedAccountException("账号背锁定");
        }
        return new  SimpleAuthenticationInfo(user,user.getUsrPassword(), ByteSource.Util.bytes("czkt"),getName());
    }

    /**
     * 登录时情况当前用户的权限缓存
     */
    public void clearMyCachedAuthorizationInfo(){
        clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }

    /**
     * 清空所有的缓存
     */
    public void clearAllCachedAuthorizationInfo(){
        //是否开启了权限缓存
        if (this.isAuthorizationCachingEnabled()){
            //拿缓存管理
            CacheManager cacheManager = this.getCacheManager();
            String authorizationCacheName = getAuthorizationCacheName();
            //判断是否有 有则情况
            Cache<Object, Object> cache = cacheManager.getCache(authorizationCacheName);
            if (cache!=null){
                cache.clear();;
            }
        }
    }
}
